package com.deskbill.tools;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.apache.commons.codec.binary.Hex;
 
/**
 * MD5密码加密
 */
public class Md5PwdEncoder  {
	 /**
     * 密码加密
     *
     * @param rawPass
     *            未加密密码，null作为空串
     * @return 加密后密码
     */
    public String encodePassword(String rawPass) {
        return encodePassword(rawPass, defaultSalt);
    }
    /**
     * 密码加密
     *
     * @param rawPass
     *            未加密密码，null作为空串
     * @param salt
     *            混淆码
     * @return
     */
    public String encodePassword(String rawPass, String salt) {
        String saltedPass = mergePasswordAndSalt(rawPass, salt, false);
        MessageDigest messageDigest = getMessageDigest();
        byte[] digest;
        try {
            digest = messageDigest.digest(saltedPass.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new IllegalStateException("UTF-8 not supported!");
        }
        return new String(Hex.encodeHex(digest));
    }
    /**
     * 验证密码是否正确
     *
     * @param encPass
     *            加密密码
     * @param rawPass
     *            未加密密码，null作为空串
     * @return true:密码正确；false:密码错误
     */
    public boolean isPasswordValid(String encPass, String rawPass) {
        return isPasswordValid(encPass, rawPass, defaultSalt);
    }
    /**
     * 验证密码是否正确
     *
     * @param encPass
     *            加密密码
     * @param rawPass
     *            未加密密码，null作为空串
     * @param salt
     *            混淆码
     * @return true:密码正确；false:密码错误
     */
    public boolean isPasswordValid(String encPass, String rawPass, String salt) {
        if (encPass == null) {
            return false;
        }
        String pass2 = encodePassword(rawPass, salt);
        return encPass.equals(pass2);
    }
 
    protected final MessageDigest getMessageDigest() {
        String algorithm = "MD5";
        try {
            return MessageDigest.getInstance(algorithm);
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalArgumentException("No such algorithm ["
                    + algorithm + "]");
        }
    }
 
    /**
     * Used by subclasses to extract the password and salt from a merged
     * <code>String</code> created using
     * {@link #mergePasswordAndSalt(String,Object,boolean)}.
     * <p>
     * The first element in the returned array is the password. The second
     * element is the salt. The salt array element will always be present, even
     * if no salt was found in the <code>mergedPasswordSalt</code> argument.
     * </p>
     *
     * @param mergedPasswordSalt
     *            as generated by <code>mergePasswordAndSalt</code>
     *
     * @return an array, in which the first element is the password and the
     *         second the salt
     *
     * @throws IllegalArgumentException
     *             if mergedPasswordSalt is null or empty.
     */
    protected String mergePasswordAndSalt(String password, Object salt,
            boolean strict) {
        if (password == null) {
            password = "";
        }
        if (strict && (salt != null)) {
            if ((salt.toString().lastIndexOf("{") != -1)
                    || (salt.toString().lastIndexOf("}") != -1)) {
                throw new IllegalArgumentException(
                        "Cannot use { or } in salt.toString()");
            }
        }
        if ((salt == null) || "".equals(salt)) {
            return password;
        } else {
            return password + "{" + salt.toString() + "}";
        }
    }
 
    /**
     * 混淆码。防止破解。
     */
    private String defaultSalt;
 
    /**
     * 获得混淆码
     *
     * @return
     */
    public String getDefaultSalt() {
        return defaultSalt;
    }
 
    /**
     * 设置混淆码
     *
     * @param defaultSalt
     */
    public void setDefaultSalt(String defaultSalt) {
        this.defaultSalt = defaultSalt;
    }
}